package http

import (
	"fmt"
	"github.com/fsnotify/fsnotify"
	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
	"github.com/spf13/viper"
	"net/http"
)

var (
	enMap                 = make(map[int32]string)
	zhMap                 = make(map[int32]string)
	enLanguagePackMissing = "en_US.yaml file is not found"
	zhLanguagePackMissing = "zh_CN.yaml 文件找不到"
)

const (
	ZhCn        = "zh_CN"
	EnUs        = "en_US"
	ParamsError = 100001
	DBError     = 100002
)

func init() {
	loadEnMap()
	loadZhMap()
}

func loadEnMap() {
	v := viper.New()
	v.SetConfigFile("langs/en_US.yaml")
	v.WatchConfig()
	v.OnConfigChange(func(e fsnotify.Event) {
		logrus.Infof("语言包：%s发生变化，重新加载语言包 ", e.Name)
		if err := v.Unmarshal(&enMap); err != nil {
			logrus.Error("解析中文语言包时发生错误:", err)
			return
		}
	})
	if err := v.ReadInConfig(); err != nil {
		logrus.Error("读取中文语言包时发生错误:", err)
		return
	}
	if err := v.Unmarshal(&enMap); err != nil {
		logrus.Error("解析中文语言包时发生错误:", err)
		return
	}
}

func loadZhMap() {
	v := viper.New()
	v.SetConfigFile("langs/zh_CN.yaml")
	v.WatchConfig()
	v.OnConfigChange(func(e fsnotify.Event) {
		logrus.Infof("语言包：%s发生变化，重新加载语言包 ", e.Name)
		if err := v.Unmarshal(&zhMap); err != nil {
			logrus.Error("解析中文语言包时发生错误:", err)
			return
		}
	})
	if err := v.ReadInConfig(); err != nil {
		logrus.Error("读取中文语言包时发生错误:", err)
		return
	}
	if err := v.Unmarshal(&zhMap); err != nil {
		logrus.Error("解析中文语言包时发生错误:", err)
		return
	}

}

func getLang(c *gin.Context) string {
	lang := c.GetHeader("lang")
	switch lang {
	case ZhCn:
		return ZhCn
	case EnUs:
		return EnUs
	default:
		return ZhCn
	}
}

func getMsg(c *gin.Context, code int32) string {
	lang := getLang(c)
	var msg string
	switch lang {
	case ZhCn:
		msg = zhMap[code]
	case EnUs:
		msg = enMap[code]
	default:
		msg = zhMap[code]
	}
	if len(msg) == 0 {
		switch lang {
		case ZhCn:
			msg = zhLanguagePackMissing
		case EnUs:
			msg = enLanguagePackMissing
		default:
			msg = zhLanguagePackMissing
		}
	}
	return msg
}

func Ok(c *gin.Context, data interface{}) {
	c.JSON(http.StatusOK, data)
}

func OkPage(c *gin.Context, li interface{}, total int64) {
	c.JSON(http.StatusOK, gin.H{"list": li, "total": total})
}

func OK204(c *gin.Context) {
	c.AbortWithStatus(http.StatusNoContent)
}

// BadWithCode 发生错误，
func BadWithCode(c *gin.Context, code int32) {
	c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"code": code, "msg": getMsg(c, code)})
}

func BadWithErr(c *gin.Context, err error) {
	c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"code": DBError, "msg": err.Error()})
}

// BadWithDB 意料之外的数据库异常
func BadWithDB(c *gin.Context, err error) {
	c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"code": DBError, "msg": err.Error()})
}

// BadWithParamsError 参数错误
func BadWithParamsError(c *gin.Context, err error) {
	c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"code": ParamsError, "msg": fmt.Sprintf("%s：%s", getMsg(c, ParamsError), err)})
}
